﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace pwestcott.Util.Tests.Essence.CompareTo
{
    [TestFixture]
    public class CompareToFieldReferenceTests
    {
        [EssenceClass(UseIn = EssenceFunctions.All)]
        class TestEssence : IComparable<TestEssence>
        {
            [Essence]
            public string MyString;

            public int CompareTo(TestEssence other)
            {
                return Essence<TestEssence>.CompareToStatic(this, other);
            }
        }

        class TestManual : IComparable<TestManual>
        {
            public string MyString;

            public int CompareTo(TestManual other)
            {
                if (other == null)
                    return -1;
                if (ReferenceEquals(this, other))
                    return 0;

                int result;

                if (MyString == null)
                {
                    if (other.MyString != null)
                        return -1;
                }
                else
                {
                    result = MyString.CompareTo(other.MyString);
                    if (result != 0)
                        return result;
                }

                return 0;
            }
        }

        [Test]
        public void NullNullTest()
        {
            var e1 = new TestEssence();
            var e2 = new TestEssence();
            var m1 = new TestManual();
            var m2 = new TestManual();

            Assert.AreEqual(0, m1.CompareTo(m2));
            Assert.AreEqual(m1.CompareTo(m2), e1.CompareTo(e2));
        }

        // TODO: Add Essence option to treat Null and string.Empty as equal - maybe tests should move to 
        // seperate string testing area (and include other functions such as case insensitive tests)
        [Test]
        public void EmptyNullTest()
        {
            var e1 = new TestEssence();
            var e2 = new TestEssence();
            var m1 = new TestManual();
            var m2 = new TestManual();

            e1.MyString = m1.MyString = "";

            Assert.AreEqual(1, m1.CompareTo(m2));
            Assert.AreEqual(m1.CompareTo(m2), e1.CompareTo(e2));
        }

        [Test]
        public void NullEmptyTest()
        {
            var e1 = new TestEssence();
            var e2 = new TestEssence();
            var m1 = new TestManual();
            var m2 = new TestManual();

            e2.MyString = m2.MyString = "";

            Assert.AreEqual(-1, m1.CompareTo(m2));
            Assert.AreEqual(m1.CompareTo(m2), e1.CompareTo(e2));
        }

        [Test]
        public void QBFNullTest()
        {
            var e1 = new TestEssence();
            var e2 = new TestEssence();
            var m1 = new TestManual();
            var m2 = new TestManual();

            e1.MyString = m1.MyString = "The Quick Brown Fox Jumps Over The Lazy Dog";

            Assert.AreEqual(1, m1.CompareTo(m2));
            Assert.AreEqual(m1.CompareTo(m2), e1.CompareTo(e2));
        }

        [Test]
        public void NullQBFTest()
        {
            var e1 = new TestEssence();
            var e2 = new TestEssence();
            var m1 = new TestManual();
            var m2 = new TestManual();

            e2.MyString = m2.MyString = "The Quick Brown Fox Jumps Over The Lazy Dog";

            Assert.AreEqual(-1, m1.CompareTo(m2));
            Assert.AreEqual(m1.CompareTo(m2), e1.CompareTo(e2));
        }

        [Test]
        public void QBFQBFTest()
        {
            var e1 = new TestEssence();
            var e2 = new TestEssence();
            var m1 = new TestManual();
            var m2 = new TestManual();

            e1.MyString = e2.MyString = m1.MyString = m2.MyString = "The Quick Brown Fox Jumps Over The Lazy Dog";

            Assert.AreEqual(0, m1.CompareTo(m2));
            Assert.AreEqual(m1.CompareTo(m2), e1.CompareTo(e2));
        }
    }
}
